package codegen.groovy.graphnetwork.model;

import java.util.ArrayList;
import codegen.graphnetwork.nodes.operartion.OpAdd

/**
 *
 * @author hungcuong
 */
public class Node {
    String name;
    int x,y;
    Status status;
    ArrayList<Value> inputs = new ArrayList<Value>();
    ArrayList<Value> outputs = new ArrayList<Value>();


    enum Status{
        Init,Computing,Finished
    }
    
    public Node(String name){
        this.name= name;
        this.status = Status.Init;
        //this.operation = new OpAdd(this);
        
    }
    
    void addInput(Value value){
        inputs.add(value);
        value.parent = this;
        value.isInput = true;
    }
    void addOutput(Value value){
        outputs.add(value)
        value.parent = this;
        value.isInput = false;
    }
    
    def findValue(String name,boolean isInput){
        if (isInput){
            return inputs.find{v->
                v.name==name
            }
        } else {
            return outputs.find{v->
                v.name==name
            }
        }
    }
    
    boolean hasValue(String name,boolean isInput){
        if (isInput){

        } else {
            
        } 
    }

    
    def getValue(String name){

        
    }
    /**
     * Recursively travel the graph from this Node to pull out result.
     * Start by Try to resovle all Node inputs
     * Then try to compute the outputs by the Operation
     * After finish mark the Node as Finished
     */
    def getResult(){
        if (status!=Status.Finished){
            //println "get result Node"+this.name
            preResolveNode();
            inputs.each{v->
                if (v.link!=null){
                    def linkedNode = v.link.input.parent
                    //println "checking link Node:" + linkedNode.name;
                    if (linkedNode.status!=Status.Finished){
                        linkedNode.getResult();
                    }
                    v.getLinkedValue();
                }
            }
            
            resovleNode();
            postResovleNode();
            // Set the finished Status
            status=Status.Finished;
        }
        return outputs[0].value
    }
    /**
     * If one of the nodes that this Node depend on has change, the Node should be mark as Changed or NotResovled
     */
    void markChanged(){
    } 
    
    public void preResovleNode(){
        
    }
    
    public void resovleNode(){
        
    }
    
    public void postResovleNode(){
        
    }
}